package com.sharedmobility.dao;

import com.sharedmobility.model.Rental;
import com.sharedmobility.util.DBUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.math.BigDecimal;

public class RentalDAO {
    private Connection getConnection() throws SQLException {
        return DBUtil.getConnection();
    }

    public Integer create(Rental rental) throws SQLException {
        String sql = "INSERT INTO rentals (vehicle_id, user_id, start_time, start_location, status) " +
                    "VALUES (?, ?, ?, ST_PointFromText(?), ?)";
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            stmt.setInt(1, rental.getVehicleId());
            stmt.setInt(2, rental.getUserId());
            stmt.setTimestamp(3, rental.getStartTime());
            
            // 处理起始位置
            if (rental.getStartLocation() != null) {
                stmt.setString(4, rental.getStartLocation());
            } else {
                stmt.setNull(4, Types.VARCHAR);
            }
            
            stmt.setInt(5, rental.getStatus());

            int affectedRows = stmt.executeUpdate();
            if (affectedRows == 0) {
                return null;
            }

            try (ResultSet generatedKeys = stmt.getGeneratedKeys()) {
                if (generatedKeys.next()) {
                    return generatedKeys.getInt(1);
                }
            }
        } catch (SQLException e) {
            System.err.println("创建租赁记录失败: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
        return null;
    }

    public boolean update(Rental rental) throws SQLException {
        String sql = "UPDATE rentals SET end_time = ?, end_location = ST_PointFromText(?), " +
                    "total_amount = ?, status = ? WHERE id = ?";
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setTimestamp(1, rental.getEndTime());
            
            // 处理结束位置
            if (rental.getEndLocation() != null) {
                stmt.setString(2, rental.getEndLocation());
            } else {
                stmt.setNull(2, Types.VARCHAR);
            }
            
            stmt.setBigDecimal(3, rental.getTotalAmount());
            stmt.setInt(4, rental.getStatus());
            stmt.setInt(5, rental.getId());

            int affectedRows = stmt.executeUpdate();
            return affectedRows > 0;
        } catch (SQLException e) {
            System.err.println("更新租赁记录失败: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
    }

    public Rental findById(Integer id) throws SQLException {
        String sql = "SELECT id, vehicle_id, user_id, start_time, end_time, " +
                    "ST_AsText(start_location) as start_location_text, " +
                    "ST_AsText(end_location) as end_location_text, " +
                    "status, total_amount, created_at, updated_at " +
                    "FROM rentals WHERE id = ?";
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, id);
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    return mapRental(rs);
                }
            }
        }
        return null;
    }

    public List<Rental> findByUserId(Integer userId) throws SQLException {
        String sql = "SELECT id, vehicle_id, user_id, start_time, end_time, " +
                    "ST_AsText(start_location) as start_location_text, " +
                    "ST_AsText(end_location) as end_location_text, " +
                    "status, total_amount, created_at, updated_at " +
                    "FROM rentals WHERE user_id = ? ORDER BY start_time DESC";
        List<Rental> rentals = new ArrayList<>();
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, userId);
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    rentals.add(mapRental(rs));
                }
            }
        }
        return rentals;
    }
    
    /**
     * 查询用户当前进行中的租赁
     * @param userId 用户ID
     * @return 进行中的租赁列表
     * @throws SQLException
     */
    public List<Rental> findActiveByUserId(Integer userId) throws SQLException {
        String sql = "SELECT id, vehicle_id, user_id, start_time, end_time, " +
                    "ST_AsText(start_location) as start_location_text, " +
                    "ST_AsText(end_location) as end_location_text, " +
                    "status, total_amount, created_at, updated_at " +
                    "FROM rentals WHERE user_id = ? AND status = 0 ORDER BY start_time DESC";
        List<Rental> rentals = new ArrayList<>();
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, userId);
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    rentals.add(mapRental(rs));
                }
            }
        }
        return rentals;
    }

    public List<Rental> findByStatus(Integer status) throws SQLException {
        String sql = "SELECT id, vehicle_id, user_id, start_time, end_time, " +
                    "ST_AsText(start_location) as start_location_text, " +
                    "ST_AsText(end_location) as end_location_text, " +
                    "status, total_amount, created_at, updated_at " +
                    "FROM rentals WHERE status = ? ORDER BY start_time DESC LIMIT 10";
        List<Rental> rentals = new ArrayList<>();
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, status);
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    rentals.add(mapRental(rs));
                }
            }
        }
        return rentals;
    }
    
    /**
     * 查询用户最近的租赁历史记录
     * @param userId 用户ID
     * @param limit 限制返回记录数
     * @return 租赁历史记录列表
     * @throws SQLException
     */
    public List<Rental> findRecentByUserId(Integer userId, int limit) throws SQLException {
        String sql = "SELECT id, vehicle_id, user_id, start_time, end_time, " +
                    "ST_AsText(start_location) as start_location_text, " +
                    "ST_AsText(end_location) as end_location_text, " +
                    "status, total_amount, created_at, updated_at " +
                    "FROM rentals WHERE user_id = ? AND status = 1 ORDER BY end_time DESC LIMIT ?";
        List<Rental> rentals = new ArrayList<>();
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, userId);
            stmt.setInt(2, limit);
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    rentals.add(mapRental(rs));
                }
            }
        }
        return rentals;
    }

    private Rental mapRental(ResultSet rs) throws SQLException {
        Rental rental = new Rental();
        rental.setId(rs.getInt("id"));
        rental.setVehicleId(rs.getInt("vehicle_id"));
        rental.setUserId(rs.getInt("user_id"));
        rental.setStartTime(rs.getTimestamp("start_time"));
        rental.setEndTime(rs.getTimestamp("end_time"));
        
        // 处理位置信息
        String startLocationText = rs.getString("start_location_text");
        String endLocationText = rs.getString("end_location_text");
        rental.setStartLocation(startLocationText);
        rental.setEndLocation(endLocationText);
        
        rental.setStatus(rs.getInt("status"));
        rental.setTotalAmount(rs.getBigDecimal("total_amount"));
        rental.setCreatedAt(rs.getTimestamp("created_at"));
        rental.setUpdatedAt(rs.getTimestamp("updated_at"));
        
        return rental;
    }
} 